#ifndef _yyh
#define _yyh

#include<iostream>
/**
 * @file   matrix.h
 * @author yyh
 * @date   Thu Oct  7  2021
 * 
 * @brief  这是一个头文件，关于矩阵运算以及其派生类行向量以及列向量的乘法运算
 * 
 * 
 */


template <typename T>
class Matrix
{
public:
    T* matrix_elements;
    int n_row, n_column;
    //初始化matrix类
    Matrix()
    {
	matrix_elements = NULL;
    n_row = 0;
	n_column = 0;
    }
    //此要求初始化的同时输入行列，以及各种元素
    //m为矩阵的行数，n为矩阵的列数
    Matrix(int m,int n)
    {
	matrix_elements = new T[m*n];
	n_row=m;
	n_column=n;
	for(int j=0; j<m*n; j++)
	std::cin>>matrix_elements[j];
	}

    //析构函数，用于释放内存
     ~Matrix(){
	if(matrix_elements != NULL)
	delete matrix_elements;
      }
     //判断函数，是否为方正
    bool is_square(){
	if(n_column==n_row)
	    return true;
	else
	    return false;
    }
    //实现矩阵的加法运算
     Matrix<T> operator + (const Matrix<T>& _obj)
    {
	Matrix<T> b;
	if(n_row!=_obj.n_row||n_column!=_obj.n_column)
	{
	    std::cout<<"false operation"<<std::endl;
	    return b;
	}
	b.n_row = n_row;
	b.n_column = n_column;
	b.matrix_elements = new T [n_row*n_column];
	for(int i=0;i<n_row;i++)
	    for(int j=0;j<n_column;j++)
		b.matrix_elements[i*n_column+j]=matrix_elements[i*n_column+j] + _obj.matrix_elements[i*n_column+j];
	return b;
    }
     //实现矩阵的减法运算
    Matrix<T> operator - (const Matrix<T>& _obj)
    {
	Matrix<T> b;
	if(n_row!=_obj.n_row||n_column!=_obj.n_column)
	{
	    std::cout<<"false operation"<<std::endl;
	    return b;
	}
	b.n_row = n_row;
	b.n_column = n_column;
	b.matrix_elements = new T [n_row*n_column];
	for(int i=0;i<n_row;i++)
	    for(int j=0;j<n_column;j++)
		b.matrix_elements[i*n_column+j]=matrix_elements[i*n_column+j] - _obj.matrix_elements[i*n_column+j];
	return b;
    }
    //重置矩阵的赋值运算符
    Matrix<T>& operator = (const Matrix<T>& _obj)
    {
	n_column=_obj.n_column;
	n_row = _obj.n_row;
	//判断是否为空指针
	if(matrix_elements != NULL)
	    delete [] matrix_elements;
	matrix_elements = new T[n_column*n_row];
	for(int i=0;i<n_row;i++)
	    for(int j=0;j<n_column;j++)
		matrix_elements[i*n_column+j] = _obj.matrix_elements[i*n_column+j];
	return *this;
       
    }
    //矩阵的乘法运算
    Matrix<T> operator * (const Matrix<T>& a)
     {
	static Matrix<T> b;
	if(n_column!=a.n_row)
	{
	    std::cout<<"false operation"<<std::endl;
	    return b;
	}
	    
	b.n_row=n_row;
	b.n_column=a.n_column;
	b.matrix_elements = new T [b.n_row*b.n_column];
	for(int i=0 ;i<b.n_row;i++)
	    for(int j=0;j<b.n_column;j++)
	    {
		b.matrix_elements[i*b.n_column+j]=0;
		for(int k=0; k<n_column;k++)
		{
		    b.matrix_elements[i*b.n_column+j]+=matrix_elements[i*n_column+k]*a.matrix_elements[k*a.n_column+j];    
		}
	    }
    return b;		    
   }
    //打印出矩阵的元素
    void print()
    {
	for(int i=0;i<n_row;i++)
	{
	  
	    for(int j=0;j<n_column;j++)
		std::cout<<matrix_elements[i*n_column+j]<<' ';
	    std::cout<<'\n';
	}
	
    }
};

template<typename T>

class RowVector:public Matrix<T>
{

public:
    
    RowVector():Matrix<T>(){}
    RowVector(int n):Matrix<T>(1,n){}
    //行向量特殊乘法，类似于向量内积
    friend T operator *(const RowVector& a, const RowVector& b)
    {
	if(a.n_column!=b.n_column)
	{
	    std::cout<<"false operation"<<std::endl;
	    return 0;
	}
	T ret=0;
	for(int i=0;i<a.n_column;i++)
	    ret += a.matrix_elements[i] * b.matrix_elements[i];
	return ret;
	    
    }
};
template<typename T>
class ColVector:public Matrix<T>
{
public:
    ColVector():Matrix<T>(){}
    ColVector(int n):Matrix<T>(n,1){}
    //列向量乘法，类似与向量的内积
    friend T operator *(const ColVector& a, const ColVector& b)
    {
	if(a.n_column!=b.n_column)
	{
	    std::cout<<"false operation"<<std::endl;
	    return 0;
	}
	T ret=0;
	for(int i=0;i<a.n_row;i++)
	    ret += a.matrix_elements[i] * b.matrix_elements[i];
	return ret;
	    
    }
    
};
//行向量与列向量的乘积类似矩阵，但是输出为T类型的变量
template <typename T>
T operator * (const RowVector<T>& a,const ColVector<T>&b)
{
    if(a.n_column!=b.n_row)
    {
	std::cout<<"false operation"<<std::endl;
	return 0;
    }
    T ret=0;
    for(int i=0;i<a.n_column;i++)
	ret+=a.matrix_elements[i]*b.matrix_elements[i];
    return ret;
	
}


#else
//DO NOTHING
#endif
